<template>
  <div class="chat-app">
    <el-aside style="background-color: aliceblue;" width="300px">
      <el-container>
        <el-aside style="background-color:aliceblue;" width="60px">
          <el-menu default-active="3" class="el-menu-vertical-demo" :collapse="true">
            <el-menu-item index="1">
              <el-tooltip content="消息列表" placement="right-start">
                <el-badge :value="messageValue" :min="1" :max="99">
                  <el-icon @click="getChatRecord">
                    <ChatDotRound />
                  </el-icon>
                </el-badge>
              </el-tooltip>
            </el-menu-item>
            <el-menu-item index="2">
              <el-tooltip content="好友申请" placement="right-start">
                <el-badge :value="applyFriendValue" :min="1" :max="99">
                  <el-icon @click="friendApply">
                    <Bell />
                  </el-icon>
                </el-badge>
              </el-tooltip>
            </el-menu-item>
            <el-menu-item index="3">
              <el-tooltip content="好友列表" placement="right-start">
                <el-icon @click="getFriendList">
                  <User />
                </el-icon>
              </el-tooltip>
            </el-menu-item>
          </el-menu>
        </el-aside>
        <el-main>
          <div style="display: flex; ">
            <el-input :prefix-icon="Search" style="width: 150px; margin-bottom: 10px;" v-model="searchInput"
              placeholder="请输入用户名" />
            <el-tooltip content="搜索好友" placement="bottom">
              <el-button @click="getFriendByAccount" style="margin-left: 10px;" type="primary"><el-icon>
                  <Search />
                </el-icon></el-button>
            </el-tooltip>
          </div>
          <el-menu>
            <el-scrollbar height="600px" width="2px">
              <el-menu-item v-for="person in filteredPersons" :index="person.id.toString" :key="person.id"
                @click="getChatListMessage(person.account, person.id, person.toEmpId, person.image)">
                <div style="display: flex;">
                  <div>
                    <img :src="person.image" style="width: 35px; height: 35px; margin-top: 5px;"></img>
                  </div>
                  <div style="margin-left: 10px; display: flex;">
                    <h4 style="margin-left: 5px;">{{ person.account }}</h4>
                  </div>
                </div>
              </el-menu-item>
            </el-scrollbar>
          </el-menu>
        </el-main>
      </el-container>
    </el-aside>
    <el-container>
      <el-header v-model="personName">
        <div style="display: flex;">
          <div>
            {{ personName }}
          </div>
          <div>
            <el-button v-if="personName" style="margin-left: 900px;" type="danger"
              @click="clearChatRecord">清空聊天记录</el-button>
          </div>
        </div>
      </el-header>
      <el-main>
        <el-card v-if="personName" class="bottom">
          <el-scrollbar class="bottom" ref="scrollbarRef">
            <div v-for="msg in messages" :key="msg.id" class="message-item">
              <img v-if="msg.fromEmpId != applyId" :src="msg.toEmpImage" style="width: 50px; height: 50px;"></img>
              <div :class="{ 'my-message': msg.fromEmpId == applyId, 'other-message': msg.fromEmpId != applyId }">
                <span v-if="msg.message && msg.message.includes('.png') || msg.text && msg.message.includes('.jpg')">
                  <img :src="msg.message" style="width: 75px;height: 75px;"></img>
                </span>
                <span
                  v-else-if="msg.message && msg.message.includes('.docx') || msg.message && msg.message.includes('.pdf') || msg.message && msg.message.includes('.xlsx')">
                  <el-link :href="msg.message">{{ msg.message }}</el-link>
                </span>
                <span v-else>{{ msg.message }}</span>
              </div>
              <img v-if="msg.fromEmpId == applyId" :src="imageUrl" style="width: 50px; height: 50px;"></img>
            </div>
          </el-scrollbar>
        </el-card>
      </el-main>
      <el-footer style="margin-bottom: 150px;">
        <el-card v-if="personName">
          <el-form :inline="true">
            <el-form-item>
              <el-upload action="/api/emp/uploadFile" :headers="getTokenFromToken" :on-success="handleAvatarSuccess"
                :show-file-list="false">
                <el-tooltip content="选择文件" placement="bottom">
                  <el-icon>
                    <FolderOpened />
                  </el-icon>
                </el-tooltip>
              </el-upload>
            </el-form-item>
          </el-form>
          <el-form :inline="true">
            <el-form-item>
              <el-input type="textarea" style="width: 900px;" v-model="inputMessage" placeholder="在这里输入"
                @keyup.enter="sendMessage">
                <span v-if="inputMessage.includes('.png') || inputMessage.includes('.jpg')">
                  <img :src="inputMessage" style="width: 75px;height: 75px;"></img>
                </span>
                <span v-else>{{ inputMessage }}</span>
              </el-input>
            </el-form-item>
            <el-form-item>
              <el-tooltip content="发送消息" placement="top">
                <el-button type="primary" @click="sendMessage"><el-icon>
                    <Top />
                  </el-icon></el-button>
              </el-tooltip>
            </el-form-item>
          </el-form>
        </el-card>
      </el-footer>
    </el-container>
  </div>
  <!-- 搜索账号添加好友 -->
  <el-dialog title="添加好友" v-model="addFriendDialogVisible" style="width: 60%; height: 60%;" draggable>
    <el-form>
      <el-form-item>
        <div style="display: flex;">
          <el-input style="width: 400px;margin-left: 150px;" v-model="searchInput" placeholder="请输入账号" />
          <el-button @click="getFriendByAccount" type="default" style="margin-left: 10px;"><el-icon>
              <Search />
            </el-icon></el-button>
        </div>
      </el-form-item>
    </el-form>
    <el-form>
      <el-scrollbar height="400px" width="2px">
        <el-form-item v-for="person in searchPersonByAccount" :index="person.id.toString" :key="person.id">
          <div style="display: flex;">
            <div style="margin-left: 150px;">
              <img :src="person.image" style="width: 50px; height: 50px;"></img>
            </div>
            <div style="margin-left: 10px; display: flex;">
              <h3>{{ person.name }}</h3>
              <h3 style="margin-left: 5px;">{{ person.account }}</h3>
            </div>
            <div style="margin-left: 200px;">
              <span v-if="person.applyStatus == 0">申请中.....</span>
              <span v-else-if="person.applyStatus == 2">你们已经是好友</span>
              <span v-else>
                <el-button type="primary" @click="applyFriend(person.id)">添加好友</el-button>
              </span>
            </div>
          </div>
        </el-form-item>
      </el-scrollbar>
    </el-form>
  </el-dialog>
  <!-- 接收好友对话框 -->
  <el-dialog title="好友申请" v-model="friendApplyDialogVisible" style="width: 60%; height: 120%;" draggable>
    <h3>我的好友申请</h3>
    <el-form>
      <el-scrollbar height="200px" width="2px">
        <el-form-item v-for="person in myFriendApplyList" :index="person.id.toString" :key="person.id">
          <div style="display: flex;">
            <div style="margin-left: 150px;">
              <img :src="person.image" style="width: 50px; height: 50px;"></img>
            </div>
            <div style="margin-left: 10px; display: flex;">
              <h3>{{ person.name }}</h3>
              <h3 style="margin-left: 5px;">{{ person.account }}</h3>
            </div>
            <div style="margin-left: 200px;">
              <span v-if="person.applyStatus == 0">申请中.....</span>
              <span v-else-if="person.applyStatus == 2">已同意</span>
              <span v-else-if="person.applyStatus == 1">已拒绝</span>
            </div>
          </div>
        </el-form-item>
      </el-scrollbar>
    </el-form>
    <h3>请求添加好友</h3>
    <el-form>
      <el-scrollbar height="200px" width="2px">
        <el-form-item v-for="person in friendApplyList" :index="person.id.toString" :key="person.id">
          <div style="display: flex;">
            <div style="margin-left: 150px;">
              <img :src="person.image" style="width: 50px; height: 50px;"></img>
            </div>
            <div style="margin-left: 10px; display: flex;">
              <h3>{{ person.name }}</h3>
              <h3 style="margin-left: 5px;">{{ person.account }}</h3>
            </div>
            <div style="margin-left: 200px;">
              <el-button type="primary" @click="agreeFriendApply(person.id, person.applyTime)">同意</el-button>
              <el-button type="primary" @click="refuseFriendApply(person.id, person.applyTime)">拒绝</el-button>
            </div>
          </div>
        </el-form-item>
      </el-scrollbar>
    </el-form>
    <h3>历史记录</h3>
    <el-form>
      <el-scrollbar height="200px" width="2px">
        <el-form-item v-for="person in friendApplyHistoryList" :index="person.id.toString" :key="person.id">
          <div style="display: flex;">
            <div style="margin-left: 150px;">
              <img :src="person.image" style="width: 50px; height: 50px;"></img>
            </div>
            <div style="margin-left: 10px; display: flex;">
              <h3>{{ person.name }}</h3>
              <h3 style="margin-left: 5px;">{{ person.account }}</h3>
            </div>
            <div style="margin-left: 200px;">
              <span v-if="person.applyStatus === 1">拒绝</span>
              <span v-else-if="person.applyStatus === 2">同意</span>
            </div>
          </div>
        </el-form-item>
      </el-scrollbar>
    </el-form>
  </el-dialog>
  <!-- 好友列表对话框 -->
  <el-dialog title="好友列表" v-model="friendListDialogVisible" style="width: 60%; height: 120%;" draggable>
    <h3>好友列表</h3>
    <el-form>
      <el-scrollbar height="200px" width="2px">
        <el-form-item v-for="person in friendList" :index="person.id.toString" :key="person.id">
          <div style="display: flex;">
            <div style="margin-left: 150px;">
              <img :src="person.image" style="width: 50px; height: 50px;"></img>
            </div>
            <div style="margin-left: 10px; display: flex;">
              <h3>{{ person.name }}</h3>
              <h3 style="margin-left: 5px;">{{ person.account }}</h3>
            </div>
            <div style="margin-left: 200px;">
              <el-button type="primary" @click="chatWithFriend(person.id)">聊天</el-button>
              <el-button type="danger" @click="deleteFriendById(person.id)">删除好友</el-button>
            </div>
          </div>
        </el-form-item>
      </el-scrollbar>
    </el-form>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, nextTick, reactive, watchEffect, watch, onUpdated, onBeforeMount } from 'vue';
import { Search, FolderOpened, Top, Plus, User, ChatDotRound, Bell } from '@element-plus/icons-vue';
import { empAccount ,msgNum} from '@/store';
import axios from '@/utils/request'
import moment from 'moment';
import { ElMessage, type UploadInstance, type UploadProps, type UploadRawFile } from 'element-plus';
import { getToken } from '@/utils/auth';

let applyFriendValue = ref(0)
const accountStore = empAccount();
const applyId = accountStore.$state.id;
const receiveId = accountStore.$state.id;
const addFriendDialogVisible = ref(false)
const friendListDialogVisible = ref(false)
const imageUrl = accountStore.$state.image;
const messages = ref([]);
const friendApplyDialogVisible = ref(false)
const searchPersonByAccount = ref([])
const friendList = ref([])
const inputMessage = ref('');
let personName = ref('');
const searchInput = ref('');
const friendApplyList = ref([]);
const friendApplyHistoryList = ref([]);
const myFriendApplyList = ref([]);
const filteredPersons = ref([])
const messageId = ref()
const toEmpId = ref()
const scrollbarRef = ref(null);
const toEmpImage = ref('');
const msgNumStore = msgNum();
let messageValue = ref(0);
msgNumStore.$state.msgNum = messageValue.value + applyFriendValue.value;
const getTokenFromToken = reactive({
  token: getToken()
});


//websocket
let socket = new WebSocket("ws://localhost:8080/chat/" + applyId);
//生命周期
onMounted(() => {
  //获取好友申请
  getFriendApplicationMsg();
  //获取我的好友申请
  getMyFriendApplicationMsg();
  //获取我的好友列表
  getChatRecord();
  //一秒发送一次获取连接请求
  setInterval(() => {
    socket.addEventListener('open', () => {
    console.log('WebSocket连接已打开');
  });
  }, 1000);
  //发送消息的方法
  socket.addEventListener('message', (event) => {
    const message = event.data;
    console.log('收到消息:', message);
    const messageObj = JSON.parse(message);
    messages.value.push(messageObj);
    messageValue.value++;
  });

  //监听socket是否关闭
  window.addEventListener('beforeunload',()=>{
    socket.close();
  })
});

//检测消息的变化
watch(messages,()=>{
  getHistoryMessage(messageId.value);
})

//组件销毁之前去除监听
onBeforeMount(() => {
  window.removeEventListener('beforeunload', () => {
    socket.close();
  });
});
//点击好友聊天后要获取历史聊天记录
const getChatListMessage = (account: any, id: any, ToEmpId: any, image: any) => {
  personName.value = account;
  messageId.value = id;
  toEmpId.value = ToEmpId;
  toEmpImage.value = image;
  //点击聊天之后还要获取历史聊天记录
  getHistoryMessage(messageId.value);
}
// 获取历史聊天记录
const getHistoryMessage = async (messageId: any) => {
  try {
    const result = await axios.get('/message/' + messageId);
    if (result.data.code === 1) {
      messages.value = result.data.data;
    } else {
      ElMessage.error('获取历史聊天记录失败');
    }
  } catch (error) {
    console.error('获取历史聊天记录时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
}


//发送消息逻辑
const sendMessage = () => {
  if (inputMessage.value.trim()) {
    messages.value.push({ id: messages.value.length + 1, messageId: messageId.value, message: inputMessage.value, fromEmpId: applyId, toEmpId: toEmpId.value });
    const message = {
      messageId: messageId.value,
      message: inputMessage.value,
      fromEmpId: applyId,
      toEmpId: toEmpId.value,
      fromEmpImage: imageUrl,
      toEmpImage: toEmpImage.value,
    };
    socket = new WebSocket("ws://localhost:8080/chat/" + applyId);
    socket.onopen = () => {
      console.log('WebSocket连接已打开');
      socket.send(JSON.stringify(message));
    };
    inputMessage.value = '';
  }
};
const handleAvatarSuccess: UploadProps['onSuccess'] = (response) => {
  inputMessage.value += response.data
  sendMessage();
};


//查找好友
const getFriendByAccount = async () => {
  if (searchInput.value === '') {
    ElMessage.warning('请输入账号')
    return;
  }
  //显示对话框
  addFriendDialogVisible.value = true;
  try {
    const result = await axios.get('/emp/friend/' + searchInput.value);
    if (result.data.code === 1) {
      searchPersonByAccount.value = result.data.data;
      //遍历集合不用显示自己的
      for (let i = 0; i < searchPersonByAccount.value.length; i++) {
        if (searchPersonByAccount.value[i].account === accountStore.$state.account) {
          searchPersonByAccount.value.splice(i, 1);
          break;
        }
      }
      if (searchPersonByAccount.value.length === 0) {
        ElMessage.warning('不存在该用户');
      } else {
        ElMessage.success('查找成功');
      }
    } else {
      ElMessage.error('查找失败');
    }
  } catch (error) {
    console.error('获取好友信息时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};
//申请好友方法
const applyFriend = async (receiveId: any) => {
  const currentTime = moment().format('YYYY-MM-DD HH:mm:ss');
  try {
    const result = await axios.post('/emp/friend', {
      applyId: applyId,
      receiveId: receiveId,
      applyTime: currentTime
    });
    if (result.data.code === 1) {
      ElMessage.success('申请成功');
      //重新找一次
      getFriendByAccount();
    } else {
      ElMessage.error('申请失败');
    }
  } catch (error) {
    console.error('申请好友时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};

const friendApply = () => {
  //显示对话框
  friendApplyDialogVisible.value = true;
  //获取好友申请
  getFriendApplicationMsg();
  //获取我的好友申请
  getMyFriendApplicationMsg();
}
//申请好友添加后查看好友的申请是否通过
const getMyFriendApplicationMsg = async () => {
  try {
    const result = await axios.get('/emp/friend/apply/' + applyId);
    if (result.data.code === 1) {
      myFriendApplyList.value = result.data.data;
    } else {
      ElMessage.error('接收失败');
    }
  } catch (error) {
    console.error('接收好友申请时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};


//接收好友申请
const getFriendApplicationMsg = async () => {
  try {
    const result = await axios.get('/emp/friend/receive/' + receiveId);
    if (result.data.code === 1) {
      friendApplyList.value = result.data.data;
      if (friendApplyList.value.length === 0) {
        return;
      }
      // 使用 filter 方法创建一个新的数组，包含未操作的好友申请
      const unhandledFriendApplyList = friendApplyList.value.filter(item => item.applyStatus === 0);

      // 将已操作的好友申请放入历史数组
      friendApplyHistoryList.value = friendApplyList.value.filter(item => item.applyStatus !== 0);

      // 更新 friendApplyList.value 为未操作的好友申请
      friendApplyList.value = unhandledFriendApplyList;

      // 消息提示
      applyFriendValue.value = friendApplyList.value.length;
    } else {
      ElMessage.error('接收失败');
    }
  } catch (error) {
    console.error('接收好友申请时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};


//同意好友申请
const agreeFriendApply = async (applyId: any, applyTime: any) => {
  const currentTime = moment().format('YYYY-MM-DD HH:mm:ss');
  const AppLyTime = moment(applyTime).format('YYYY-MM-DD HH:mm:ss');
  try {
    const result = await axios.put('/emp/friend/agree', {
      applyId: applyId,
      receiveId: receiveId,
      addTime: currentTime,
      applyTime: AppLyTime
    });
    if (result.data.code === 1) {
      ElMessage.success('同意成功');
      //重新获取好友申请
      getFriendApplicationMsg();
      //重新获取我的好友申请
      getMyFriendApplicationMsg();
    } else {
      ElMessage.error('同意失败');
    }
  } catch (error) {
    console.error('接收好友申请时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};


//删除好友
const deleteFriendById = async (friendId: any) => {
  try {
    const result = await axios.delete('/emp/friend/list', {
      params: {
        applyId: applyId,
        friendId: friendId
      }
    });
    if (result.data.code === 1) {
      ElMessage.success('删除成功');
      //重新获取好友列表
      getFriendList();
      //重新获取我的好友列表
      getChatRecord();
      //聊天界面消失
      personName.value = '';
    } else {
      ElMessage.error('删除失败');
    }
  } catch (error) {
    console.error('接收好友申请时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};

//拒绝好友申请
const refuseFriendApply = async (applyId: any, applyTime: any) => {
  const AppLyTime = moment(applyTime).format('YYYY-MM-DD HH:mm:ss');
  try {
    const result = await axios.put('/emp/friend/refuse', {
      applyId: applyId,
      receiveId: receiveId,
      applyTime: AppLyTime
    });
    if (result.data.code === 1) {
      ElMessage.success('拒绝成功');
      //重新获取好友申请
      getFriendApplicationMsg();
      //重新获取我的好友申请
      getMyFriendApplicationMsg();
    } else {
      ElMessage.error('拒绝失败');
    }
  } catch (error) {
    console.error('接收好友申请时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};

//获取好友列表
const getFriendList = async () => {
  //显示对话框
  friendListDialogVisible.value = true;
  try {
    const result = await axios.get('/emp/friend/list/' + applyId);
    if (result.data.code === 1) {
      friendList.value = result.data.data;
    } else {
      ElMessage.error('获取好友列表失败');
    }
  } catch (error) {
    console.error('获取好友列表时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};

//添加聊天室，点击聊天后跳转方法
const chatWithFriend = async (friendId: any) => {
  //遍历消息列表集合，如果消息列表已经有了就提示并返回
  for (let i = 0; i < filteredPersons.value.length; i++) {
    if (filteredPersons.value[i].toEmpId === friendId) {
      ElMessage.warning('该好友已经在消息列表了哦');
      //关闭对话框
      friendApplyDialogVisible.value = false;
      return;
    } else if (filteredPersons.value[i].fromEmpId === friendId) {
      ElMessage.warning('该好友已经在消息列表了哦');
      //关闭对话框
      friendApplyDialogVisible.value = false;
      return;
    }
  }
  try {
    const result = await axios.post(`/message/list`, {
      fromEmpId: applyId,
      toEmpId: friendId
    });
    if (result.data.code === 1) {
      //关闭对话框
      friendListDialogVisible.value = false;
      //聊天信息列表
      getChatRecord();
    } else {
      ElMessage.error('获取聊天记录失败');
    }
  } catch (error) {
    console.error('获取聊天记录时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};

//获取聊天信息列
const getChatRecord = async () => {
  try {
    const result = await axios.get('/message/list', {
      params: {
        fromEmpId: applyId
      }
    });
    if (result.data.code === 1) {
      filteredPersons.value = result.data.data
    } else {
      ElMessage.error('获取聊天记录失败');
    }
  } catch (error) {
    console.error('获取聊天记录时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};
//清空聊天记录
const clearChatRecord = async () => {
  try {
    const result = await axios.delete('/message/' + messageId.value);
    if (result.data.code === 1) {
      ElMessage.success('清空成功');
      //重新获取聊天信息列
      getHistoryMessage(messageId.value);
    } else {
      ElMessage.error('清空失败');
    }
  } catch (error) {
    console.error('获取聊天记录时出错:', error);
    ElMessage.error('网络错误，请稍后再试');
  }
};
</script>

<style>
.chat-app {
  display: flex;
  height: 100vh;
}

.el-aside {
  background-color: #333;
  color: white;
}

.el-header {
  background-color: #b3c0d1;
  color: #333;
  text-align: center;
  line-height: 60px;
}

.el-main {
  padding: 20px;
}

.message-container {
  width: 95%;
  display: flex;
  flex-direction: column-reverse;
  gap: 10px;
  overflow-y: scroll;
  flex: 1;

}

.bottom {
  display: flex;
  overflow-y: auto;
  flex: 1%;
  flex-direction: column-reverse;
}

.message-item {
  position: relative;
  display: flex;
  justify-content: flex-end;
}

.my-message {
  display: inline-block;
  padding: 10px;
  margin: 5px;
  background-color: #f0f0f0;
  border-radius: 5px;
  min-width: 50px;
  max-width: 70%;
  text-align: left;
  word-wrap: break-word;
  word-break: break-word;
}

.other-message {
  background-color: #abbaaf;
  margin: 5px;
  padding: 10px;
  border-radius: 5px;
  max-width: 70%;
  margin-right: auto;
  word-break: break-word;
  text-align: right;
  margin-left: 5px;
}

.other-image {
  display: inline-block;
  margin-right: auto;
}

.input-area {
  display: flex;
  margin-top: 50px;
}

.tooltip {
  background-color: #f0f0f0;
}
</style>